//-----------------------------------------------------------------------
// <copyright file="UsingBlockAcceptanceTest.cs" company="NMock2">
//
//   http://www.sourceforge.net/projects/NMock2
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.
// </copyright>
// This is the easiest way to ignore StyleCop rules on this file, even if we shouldn't use this tag:
// <auto-generated />
//-----------------------------------------------------------------------
namespace NMock2.AcceptanceTests
{
    using System;
    using NMock2.Internal;
    using NUnit.Framework;

    [TestFixture]
    public class UsingBlockAcceptanceTest : AcceptanceTestBase
    {
        public interface IUsingBlock
        {
            int IntReturnValue();
            void NoReturnValue();
        }

        [TestFixtureSetUp]
        public void TestFixtureSetUp()
        {
            SkipVerificationForThisFixture();
        }

        [Test, ExpectedException(typeof(ExpectationException))]
        public void AssertsExpectationsAreMetAtEndOfUsingBlock()
        {           
            using(Mockery mocks = new Mockery())
            {
                IHelloWorld helloWorld = (IHelloWorld)mocks.NewMock(typeof(IHelloWorld));
                
                Expect.Once.On(helloWorld).Method("Hello").WithNoArguments();
            }
        }

        /// <summary>
        /// That is a test with the expected behaviour. An InvalidOperationException will be
        /// thrown, if the developer forgot to set the return value for a Value Type.
        /// </summary>
        [Test, ExpectedException(typeof(InvalidOperationException))]
        public void ReturnValueForgottenWithVerify()
        {
            IUsingBlock usingBlock = Mocks.NewMock<IUsingBlock>();

            Expect.Once.On(usingBlock).Method("IntReturnValue"); // Developer forgot to set: .Will(Return.Value(12));
            Expect.Once.On(usingBlock).Method("NoReturnValue");
            usingBlock.IntReturnValue();
            usingBlock.NoReturnValue();
        }

        /// <summary>
        /// That is a test where the InvalidOperationException will be hidden by the ExpectationException
        /// which is thrown at the Dispose() while executing the using's end block.
        /// </summary>
        [Test, ExpectedException(typeof(InvalidOperationException))]
        [Ignore("This behaviour should be fixed in a future release.")]
        public void ReturnValueForgottenWithUsingBlock()
        {
            using (Mockery mocks = new Mockery())
            {
                IUsingBlock usingBlock = mocks.NewMock<IUsingBlock>();

                Expect.Once.On(usingBlock).Method("IntReturnValue");
                Expect.Once.On(usingBlock).Method("NoReturnValue");
                usingBlock.IntReturnValue();
                usingBlock.NoReturnValue();
            }
        }

    }
}
